package com.minimalist.basic.config.request;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.minimalist.basic.utils.Sm4Util;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * @author 11987
 */
@ControllerAdvice
@Slf4j
public class DecryptRequestBodyAdvice implements RequestBodyAdvice {

    @Override
    public boolean supports(@NotNull MethodParameter methodParameter, @NotNull Type targetType
            , @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @NotNull
    @Override
    public HttpInputMessage beforeBodyRead(@NotNull HttpInputMessage inputMessage
            , @NotNull MethodParameter parameter, @NotNull Type targetType
            , @NotNull Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
        InputStream inputStream = inputMessage.getBody();
        String data = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
        log.info("请求头: {}, 请求参数: {}", inputMessage.getHeaders(), data);
        if (StrUtil.isNotBlank(data)) {
            JSONObject jsonObject = JSONObject.parseObject(data);
            String encryptedData = jsonObject.getString("data");
            if (StrUtil.isNotBlank(encryptedData)) {
                String decryptedData = Sm4Util.decrypt(encryptedData);
                log.info("请求头: {}, 解密后的参数: {}", inputMessage.getHeaders(), decryptedData);
                return new DecryptHttpInputMessage(inputMessage, decryptedData);
            }
        }
        return inputMessage;
    }

    @NotNull
    @Override
    public Object afterBodyRead(@NotNull Object body
            , @NotNull HttpInputMessage inputMessage
            , @NotNull MethodParameter parameter
            , @NotNull Type targetType
            , @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }

    @Override
    public Object handleEmptyBody(Object body, @NotNull HttpInputMessage inputMessage
            , @NotNull MethodParameter parameter, @NotNull Type targetType
            , @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }
}
